// Canvas渲染器模块 - 用于导入JSON模板并渲染到画布
import { Canvas, Textbox, Image, Group, Rect, Text, Line } from 'fabric';
import { jsPDF } from 'jspdf';
import JsBarcode from 'jsbarcode';

// 默认像素/毫米比例
const DEFAULT_PX_PER_MM = 3.78;

class CanvasRenderer {
  constructor() {
    this.fabricInstance = null;
    this.pxPerMmValue = DEFAULT_PX_PER_MM;
    this.isCanvasReady = false;
    this.templateData = null;
    this.canvasElement = null;
    this.templateName = '预览模板';
    this.textFields = [];
    this.barcodeFields = [];
    this.tableFields = [];
    this.tableEditorData = {};
    // 默认打印时间字段ID
    this.printTimeFieldId = 'printTime';
  }

  // 毫米转像素
  mmToPx(mm) {
    if (!mm && mm !== 0) return 0;
    return mm * this.pxPerMmValue;
  }

  // 像素转毫米
  pxToMm(px) {
    if (!px && px !== 0) return 0;
    return px / this.pxPerMmValue;
  }

  /**
   * 初始化画布
   * @param {string|HTMLCanvasElement|Object} canvasIdOrElement - Canvas元素ID或DOM元素或Vue ref
   * @param {number} width - 画布宽度（毫米）
   * @param {number} height - 画布高度（毫米）
   * @param {number} pxPerMm - 像素/毫米比例，默认为3.78
   * @param {boolean} interactive - 是否允许交互，默认为false
   * @returns {Promise<boolean>} 初始化是否成功
   */
  async initCanvas(canvasIdOrElement, width, height, pxPerMm = DEFAULT_PX_PER_MM, interactive = false) {
    try {
      console.log('开始初始化画布, 类型:', typeof canvasIdOrElement);
      
      // 获取Canvas DOM元素
      let canvasElement;
      
      if (typeof canvasIdOrElement === 'string') {
        // 如果传入的是ID字符串
        console.log('通过ID查找canvas元素:', canvasIdOrElement);
        canvasElement = document.getElementById(canvasIdOrElement);
        if (!canvasElement) {
          console.error(`找不到ID为 ${canvasIdOrElement} 的canvas元素`);
          // 尝试通过选择器查找
          const canvasByQuery = document.querySelector(`canvas#${canvasIdOrElement}, canvas[id="${canvasIdOrElement}"]`);
          if (canvasByQuery) {
            console.log('通过选择器找到canvas元素');
            canvasElement = canvasByQuery;
          } else {
            throw new Error(`找不到ID为 ${canvasIdOrElement} 的canvas元素`);
          }
        }
      } else if (canvasIdOrElement instanceof HTMLCanvasElement) {
        // 如果传入的是DOM元素
        console.log('传入的是HTMLCanvasElement');
        canvasElement = canvasIdOrElement;
      } else if (canvasIdOrElement && canvasIdOrElement.tagName === 'CANVAS') {
        // 处理可能是Vue ref的情况
        console.log('传入的似乎是带有tagName的DOM元素');
        canvasElement = canvasIdOrElement;
      } else if (canvasIdOrElement && canvasIdOrElement.nodeName === 'CANVAS') {
        // 另一种DOM元素检测
        console.log('传入的似乎是带有nodeName的DOM元素');
        canvasElement = canvasIdOrElement;
      } else if (canvasIdOrElement && typeof canvasIdOrElement === 'object') {
        // 可能是Vue的ref对象
        console.log('传入的是对象类型，尝试检查是否为Vue ref');
        
        if (canvasIdOrElement.value && 
            (canvasIdOrElement.value instanceof HTMLCanvasElement || 
             canvasIdOrElement.value.tagName === 'CANVAS' || 
             canvasIdOrElement.value.nodeName === 'CANVAS')) {
          console.log('从Vue ref中提取canvas元素');
          canvasElement = canvasIdOrElement.value;
        } else {
          // 最后尝试直接找页面中的canvas元素
          console.log('尝试在文档中查找任意canvas元素');
          const anyCanvas = document.getElementById('previewCanvas') || 
                         document.querySelector('canvas');
          
          if (anyCanvas) {
            console.log('在文档中找到canvas元素');
            canvasElement = anyCanvas;
          } else {
            throw new Error('无效的canvas元素或ID，且无法在文档中找到canvas元素');
          }
        }
      } else {
        // 最后尝试查找任何canvas元素
        console.log('参数类型不匹配，尝试在文档中查找canvas元素');
        const anyCanvas = document.getElementById('previewCanvas') || 
                       document.querySelector('canvas');
        
        if (anyCanvas) {
          console.log('在文档中找到canvas元素');
          canvasElement = anyCanvas;
        } else {
          throw new Error('无效的canvas元素或ID，且无法在文档中找到canvas元素');
        }
      }
      
      if (!canvasElement) {
        throw new Error('无法获取有效的canvas元素');
      }
      
      console.log('成功获取canvas元素:', canvasElement);
      this.canvasElement = canvasElement;
      
      // 销毁旧的Fabric实例（如果存在）
      if (this.fabricInstance) {
        this.fabricInstance.dispose();
        this.fabricInstance = null;
      }
      
      // 存储pxPerMm值供后续使用
      this.pxPerMmValue = pxPerMm;
      
      // 计算像素尺寸
      const pixelWidth = Math.round(width * pxPerMm);
      const pixelHeight = Math.round(height * pxPerMm);
      
      console.log(`创建Fabric画布实例, 尺寸: ${pixelWidth}x${pixelHeight}px`);
      
      // 创建新的Fabric实例
      this.fabricInstance = new Canvas(canvasElement, {
        width: pixelWidth,
        height: pixelHeight,
        backgroundColor: '#FFFFFF',
        selection: interactive, // 是否允许选择对象
        hoverCursor: interactive ? 'pointer' : 'default',
        moveCursor: interactive ? 'move' : 'default',
      });
      
      // 设置交互选项
      this.fabricInstance.selection = interactive;
      this.fabricInstance.interactive = interactive;
      
      console.log('画布初始化成功:', pixelWidth, 'x', pixelHeight, 'px');
      this.isCanvasReady = true;
      return true;
    } catch (error) {
      console.error('初始化画布失败:', error);
      this.isCanvasReady = false;
      return false;
    }
  }

  /**
   * 渲染JSON数据到画布 - 简化版入口函数
   * @param {Object|string} jsonData - JSON数据对象或字符串
   * @param {string|HTMLCanvasElement} canvasIdOrElement - Canvas元素ID或DOM元素
   * @param {Object} options - 选项
   * @param {Function} options.onSuccess - 成功回调
   * @param {Function} options.onError - 错误回调
   * @param {Function} options.onLoading - 加载状态回调
   * @returns {Promise<boolean>} 渲染是否成功
   */
  async renderJsonData(jsonData, canvasIdOrElement, options = {}) {
    try {
      const { onSuccess = () => {}, onError = () => {}, onLoading = () => {} } = options;
      
      // 显示加载状态
      onLoading(true, '正在解析JSON数据...');
      
      // 解析JSON（如果是字符串）
      const parsedData = typeof jsonData === 'string' ? JSON.parse(jsonData) : jsonData;
      this.templateData = parsedData;
      
      // 提取基本信息
      if (parsedData.title) {
        this.templateName = parsedData.title;
      }
      
      // 获取画布尺寸信息
      const canvasWidth = parsedData.canvas?.width || 210; // 默认A4宽度
      const canvasHeight = parsedData.canvas?.height || 297; // 默认A4高度
      const pxPerMm = parsedData.canvas?.pxPerMm || DEFAULT_PX_PER_MM;
      
      // 更新加载状态
      onLoading(true, '正在初始化画布...');
      
      // 初始化画布
      const canvasReady = await this.initCanvas(canvasIdOrElement, canvasWidth, canvasHeight, pxPerMm, false);
      
        if (!canvasReady) {
          throw new Error('画布初始化失败');
        }
      
      // 更新加载状态
      onLoading(true, '正在渲染对象...');
      
      // 提取字段数据
      this.extractFields(parsedData);
      
      // 渲染画布内容
      await this.renderFromJSON(parsedData);
      
      // 成功回调
      onSuccess({
        templateName: this.templateName,
        canvasWidth,
        canvasHeight,
        pxPerMm,
        textFields: this.textFields,
        barcodeFields: this.barcodeFields,
        tableFields: this.tableFields,
        tableEditorData: this.tableEditorData
      });
      
      // 隐藏加载状态
      onLoading(false);
      
      return true;
    } catch (error) {
      console.error('渲染JSON数据失败:', error);
      if (options.onError) {
        options.onError(error);
      }
      if (options.onLoading) {
        options.onLoading(false);
      }
      return false;
    }
  }

  /**
   * 从上传的文件中导入JSON并渲染
   * @param {File} file - 上传的JSON文件
   * @param {string|HTMLCanvasElement} canvasIdOrElement - Canvas元素ID或DOM元素
   * @param {Object} options - 选项
   * @returns {Promise<boolean>} 渲染是否成功
   */
  async importJsonFromFile(file, canvasIdOrElement, options = {}) {
    if (!file) {
      if (options.onError) {
        options.onError(new Error('无效的文件'));
      }
      return false;
    }
    
    const { onSuccess = () => {}, onError = () => {}, onLoading = () => {} } = options;
    
    // 显示加载状态
    onLoading(true, '正在加载模板文件...');
    
    return new Promise((resolve) => {
      const reader = new FileReader();
      
      reader.onload = async (e) => {
        try {
          const jsonContent = e.target.result;
          // 调用渲染JSON数据函数
          const success = await this.renderJsonData(jsonContent, canvasIdOrElement, options);
          resolve(success);
        } catch (error) {
          console.error('读取文件失败:', error);
          onError(error);
          onLoading(false);
          resolve(false);
        }
      };
      
      reader.onerror = (error) => {
        console.error('读取文件失败:', error);
        onError(error);
        onLoading(false);
        resolve(false);
      };
      
      // 开始读取文件
      reader.readAsText(file.raw || file);
    });
  }

  /**
   * 提取模板中的字段数据
   * @param {Object} parsedData - 解析后的JSON数据
   * @private
   */
  extractFields(parsedData) {
    // 重置字段数组
    this.textFields = [];
    this.barcodeFields = [];
    this.tableFields = [];
    this.tableEditorData = {};
    
    if (parsedData.objects && parsedData.objects.length > 0) {
      parsedData.objects.forEach(obj => {
        if (obj.type === 'text') {
          this.textFields.push(obj);
        } else if (obj.type === 'barcode') {
          // 保存原始条形码值以便验证
          obj.originalBarcodeValue = obj.barcodeValue;
          this.barcodeFields.push(obj);
        } else if (obj.type === 'table') {
          this.tableFields.push(obj);
          
          // 为表格字段初始化编辑数据
          try {
            const fieldName = obj.fieldName || obj.key;
            if (obj.initialData) {
              const tableConfig = JSON.parse(obj.initialData);
              this.tableEditorData[fieldName] = {
                headers: tableConfig.headers || [],
                tableData: [...(tableConfig.tableData || [])]
              };
            }
          } catch (tableErr) {
            console.error('初始化表格编辑数据失败:', tableErr);
          }
        }
      });
    }
  }

  /**
   * 从JSON导入模板并渲染到画布
   * @param {Object|string} jsonData - JSON模板数据或JSON字符串
   * @returns {Promise<boolean>} 渲染是否成功
   * @public
   */
  async renderFromJSON(jsonData) {
    try {
      console.log('开始从JSON渲染模板');
      
      // 检查fabric实例
      if (!this.fabricInstance) {
        console.error('Fabric实例不存在，无法渲染');
        return false;
      }
      
      // 如果传入的是字符串，则解析为对象
      const parsedData = typeof jsonData === 'string' ? JSON.parse(jsonData) : jsonData;
      
      console.log('准备渲染数据，画布尺寸:', 
        this.fabricInstance.getWidth() + 'x' + this.fabricInstance.getHeight() + 'px');
      
      // 清空画布并设置背景色
      console.log('清空画布');
      this.fabricInstance.clear();
      this.fabricInstance.backgroundColor = '#FFFFFF';
      this.fabricInstance.renderAll();
      
      // 检查JSON数据有效性
      if (!parsedData.objects || !Array.isArray(parsedData.objects)) {
        console.error('JSON数据无效: 缺少objects数组');
        return false;
      }
      
      console.log(`开始渲染 ${parsedData.objects.length} 个对象`);
      
      // 渲染对象
      if (parsedData.objects && parsedData.objects.length > 0) {
        // 处理每个对象
        let successCount = 0;
        let failCount = 0;
        
        for (let i = 0; i < parsedData.objects.length; i++) {
          const obj = parsedData.objects[i];
          try {
            console.log(`处理对象 ${i+1}/${parsedData.objects.length}, 类型: ${obj.type}`);
            
            if (!obj.initialData) {
              console.warn(`对象 ${i+1} 缺少initialData属性，跳过`);
              failCount++;
              continue;
            }
            
              // 解析initialData
            let fieldConfig;
            try {
              fieldConfig = JSON.parse(obj.initialData);
              console.log(`成功解析对象 ${i+1} 的initialData`);
            } catch (parseError) {
              console.error(`对象 ${i+1} 的initialData解析失败:`, parseError);
              failCount++;
              continue;
            }
              
              // 添加位置信息
              fieldConfig.position = { x: obj.left, y: obj.top };
              fieldConfig.width = obj.width;
              fieldConfig.height = obj.height;
              fieldConfig.type = obj.type;
              fieldConfig.key = obj.fieldName;
              
              // 特殊处理不同类型的对象
              if (obj.type === 'barcode') {
              console.log(`处理条形码对象: ${obj.fieldName}`);
                fieldConfig.barcodeValue = obj.barcodeValue;
                fieldConfig.barcodeFormat = obj.barcodeFormat;
                fieldConfig.displayValue = obj.displayValue;
                fieldConfig.border = fieldConfig.border || { show: false };
              }
              
              // 渲染字段
            const result = await this.renderField(fieldConfig);
            if (result) {
              successCount++;
              console.log(`对象 ${i+1} 渲染成功`);
            } else {
              failCount++;
              console.warn(`对象 ${i+1} 渲染失败`);
            }
          } catch (error) {
            console.error(`处理对象 ${i+1} 失败:`, error);
            failCount++;
          }
        }
        
        console.log(`渲染结果: ${successCount} 个成功, ${failCount} 个失败`);
      }
      
      // 最终渲染画布
      console.log('执行最终画布渲染');
      this.fabricInstance.renderAll();
      
      // 返回渲染结果
      return true;
    } catch (error) {
      console.error('从JSON渲染模板失败:', error);
      return false;
    }
  }

  /**
   * 渲染单个字段
   * @param {Object} fieldConfig - 字段配置
   * @returns {Promise<Object|null>} 添加的对象或null
   */
  async renderField(fieldConfig) {
    try {
      console.log(`开始渲染字段: 类型=${fieldConfig.type}, 名称=${fieldConfig.key}`);
      
      // 检查必要参数是否存在
      if (!fieldConfig.type) {
        console.error('渲染字段失败: 字段类型未指定');
        return null;
      }
      
      if (!this.fabricInstance) {
        console.error('渲染字段失败: Fabric实例不存在');
        return null;
      }
      
      // 获取字段位置坐标，转换为像素
      const position = fieldConfig.position || { x: 20, y: 20 };
      const left = this.mmToPx(position.x);
      const top = this.mmToPx(position.y);
      
      console.log(`字段位置: ${position.x}mm, ${position.y}mm => ${left}px, ${top}px`);
      
      let renderedObject = null;
      
      // 根据字段类型渲染不同的对象
      if (fieldConfig.type === 'barcode') {
        // 渲染条形码
        console.log('渲染条形码字段');
        const sampleContent = fieldConfig.sampleContent || '1234567890';
        const actualContent = fieldConfig.barcodeValue || sampleContent;
        
        console.log(`条形码内容: ${actualContent}, 格式: ${fieldConfig.barcodeFormat || 'CODE128'}`);
        
        // 处理边框设置
        const border = fieldConfig.border || { show: false };
        
        try {
          renderedObject = await this.addBarcode(actualContent, left, top, {
          width: fieldConfig.width || 60,
          height: fieldConfig.height || 15,
          format: fieldConfig.barcodeFormat || 'CODE128',
          displayValue: fieldConfig.displayValue !== false,
          fieldName: fieldConfig.key,
          originX: 'left',
          originY: 'top',
          border: border,
          textTemplate: fieldConfig.textTemplate || '${data}',
          customData: { ...fieldConfig }
        });
          
          if (renderedObject) {
            console.log('条形码渲染成功');
          } else {
            console.error('条形码渲染失败: 添加对象未返回');
          }
        } catch (barcodeError) {
          console.error('条形码渲染异常:', barcodeError);
          return null;
        }
      } else if (fieldConfig.type === 'line') {
        // 渲染线条
        console.log('渲染线条字段');
        try {
          renderedObject = this.addLine(left, top, fieldConfig);
          if (renderedObject) {
            console.log('线条渲染成功');
          } else {
            console.error('线条渲染失败: 添加对象未返回');
          }
        } catch (lineError) {
          console.error('线条渲染异常:', lineError);
          return null;
        }
      } else if (fieldConfig.type === 'table') {
        // 渲染表格
        console.log('渲染表格字段');
        
        // 安全检查表格数据
        const hasHeaders = Array.isArray(fieldConfig.headers) && fieldConfig.headers.length > 0;
        const hasData = Array.isArray(fieldConfig.tableData);
        
        console.log(`表格数据: ${hasHeaders ? fieldConfig.headers.length : 0} 列, ${hasData ? fieldConfig.tableData.length : 0} 行`);
        
        const tableOptions = {
          key: fieldConfig.key,
          label: fieldConfig.label,
          type: fieldConfig.type,
          rows: fieldConfig.rows || 3,
          cols: fieldConfig.cols || 3,
          cellWidth: fieldConfig.cellWidth || 15,
          cellHeight: fieldConfig.cellHeight || 10,
          strokeColor: fieldConfig.strokeColor || '#000000',
          strokeWidth: fieldConfig.strokeWidth || 1,
          fieldName: fieldConfig.key,
          width: fieldConfig.width,
          height: fieldConfig.height,
          hasHeader: fieldConfig.hasHeader === true,
          headerBackgroundColor: fieldConfig.headerBackgroundColor || '#f2f2f2',
          headerTextColor: fieldConfig.headerTextColor || '#333333',
          headerFontSize: fieldConfig.headerFontSize || 12,
          headerBold: fieldConfig.headerBold === true,
          headers: fieldConfig.headers || [],
          tableData: fieldConfig.tableData || []
        };
        
        try {
          renderedObject = this.addTable(left, top, tableOptions);
          if (renderedObject) {
            console.log('表格渲染成功');
          } else {
            console.error('表格渲染失败: 添加对象未返回');
          }
        } catch (tableError) {
          console.error('表格渲染异常:', tableError);
          return null;
        }
      } else if (fieldConfig.type === 'text') {
        // 渲染文本
        console.log('渲染文本字段');
        const displayText = fieldConfig.textTemplate || `${fieldConfig.label || ''}: ${fieldConfig.key || ''}`;
        
        console.log(`文本内容: ${displayText.substring(0, 30)}${displayText.length > 30 ? '...' : ''}`);
        
        // 边框设置
        const borderOptions = fieldConfig.border || {
          show: true,
          color: '#333333',
          width: 1,
          dashArray: null,
          padding: 8,
          top: fieldConfig.border?.top === true,
          right: fieldConfig.border?.right === true,
          bottom: fieldConfig.border?.bottom === true,
          left: fieldConfig.border?.left === true
        };
        
        // 字体大小
        const fontSize = fieldConfig.style ? fieldConfig.style.fontSize : 14;
        
        try {
          renderedObject = this.addText(displayText, left, top, {
          fontSize: fontSize,
          fontWeight: fieldConfig.style && fieldConfig.style.bold ? 'bold' : 'normal',
          fill: fieldConfig.style ? fieldConfig.style.color : '#000000',
          width: this.mmToPx(fieldConfig.width),
          customHeight: this.mmToPx(fieldConfig.height),
          originX: 'left',
          originY: 'top',
          border: borderOptions,
          customType: 'field',
          fieldName: fieldConfig.key,
          fieldType: 'text',
          textTemplate: fieldConfig.textTemplate,
          customData: { ...fieldConfig },
          autoWidth: true
        });
          
          if (renderedObject) {
            console.log('文本渲染成功');
          } else {
            console.error('文本渲染失败: 添加对象未返回');
          }
        } catch (textError) {
          console.error('文本渲染异常:', textError);
      return null;
        }
      } else {
        console.warn(`未知字段类型: ${fieldConfig.type}, 字段名: ${fieldConfig.key}`);
      }
      
      // 如果渲染成功，更新画布
      if (renderedObject) {
        try {
          this.fabricInstance.renderAll();
        } catch (renderError) {
          console.error('渲染更新画布失败:', renderError);
        }
      }
      
      return renderedObject;
    } catch (error) {
      console.error('渲染字段失败:', error);
      return null;
    }
  }
  
  /**
   * 初始化文本字段内容
   * @returns {Array} 更新后的文本字段数组
   */
  initTextFieldContents() {
    return this.textFields.map(field => {
      try {
        const newField = { ...field };
        // 检查是否为自定义文本
        if (newField.fieldName && newField.fieldName.startsWith('customTitle_')) {
          // 从initialData中提取当前的textTemplate作为初始值
          if (newField.initialData) {
            const data = JSON.parse(newField.initialData);
            newField.contentValue = data.textTemplate || '';
          } else {
            newField.contentValue = '';
          }
        } else {
          // 普通文本字段设空值
          newField.contentValue = '';
        }
        return newField;
      } catch (e) {
        console.error('初始化文本字段内容失败:', e);
        return { ...field, contentValue: '' };
      }
    });
  }

  /**
   * 获取提取的字段数据
   * @returns {Object} 字段数据对象
   */
  getFieldsData() {
    return {
      textFields: this.textFields,
      barcodeFields: this.barcodeFields,
      tableFields: this.tableFields,
      tableEditorData: this.tableEditorData
    };
  }

  /**
   * 导出为PDF
   * @param {string} filename - 文件名，默认使用模板名
   * @param {Object} options - 导出选项
   * @param {number} [options.pages=1] - PDF页数，默认为1页
   * @param {boolean} [options.repeatContent=true] - 是否重复第一页内容，默认为true
   * @returns {Promise<void>} Promise
   */
  async exportToPDF(filename = null, options = {}) {
    if (!this.isCanvasReady || !this.fabricInstance) {
      throw new Error('画布未准备好');
    }

    const originalBg = this.fabricInstance.backgroundColor;
    
    try {
      // 创建加载提示
      if (options.onLoading) {
        options.onLoading(true, '正在准备导出PDF (1/4)...');
      }
      
      // 获取自定义页数设置
      const pageCount = options.pages && options.pages > 0 ? parseInt(options.pages) : 1;
      const repeatContent = options.repeatContent !== false; // 默认为true
      
      // 设置背景色
      this.fabricInstance.backgroundColor = '#FFFFFF';
      this.fabricInstance.renderAll();
      
      // 获取画布尺寸
      const canvasWidth = this.fabricInstance.getWidth();
      const canvasHeight = this.fabricInstance.getHeight();
      
      // 计算毫米尺寸
      const pxPerMm = this.pxPerMmValue;
      const widthMM = canvasWidth / pxPerMm;
      const heightMM = canvasHeight / pxPerMm;
      
      // 确定PDF方向
      const orientation = widthMM > heightMM ? 'landscape' : 'portrait';
      
      console.log(`画布尺寸: ${canvasWidth}x${canvasHeight}px, 毫米尺寸: ${widthMM}x${heightMM}mm`);
      console.log(`PDF页数: ${pageCount}, 是否重复内容: ${repeatContent}`);
      
      // 在导出前先执行一次完整的渲染
      if (options.onLoading) {
        options.onLoading(true, '正在渲染画布 (2/4)...');
      }
      await new Promise(resolve => setTimeout(resolve, 100)); // 给UI更新一点时间
      this.fabricInstance.renderAll();
      
      // 创建PDF文档
      const pdf = new jsPDF({
        orientation: orientation,
        unit: 'mm',
        format: [widthMM, heightMM],
        compress: true
      });

      // 动态调整multiplier以获得更清晰的图像
      let multiplier = 3;
      if (canvasWidth * canvasHeight > 1000000) {
        multiplier = 3;
      }
      if (canvasWidth * canvasHeight > 2000000) {
        multiplier = 2;
      }
      
      // 获取高质量图像数据
      if (options.onLoading) {
        options.onLoading(true, `正在生成高清图像 (3/4)...`);
      }
      await new Promise(resolve => setTimeout(resolve, 100));
      
      const dataURL = this.fabricInstance.toDataURL({
        format: 'png',
        quality: 1.0,
        multiplier: multiplier,
        backgroundColor: '#FFFFFF'
      });
      
      // 比例计算
      const imgRatio = canvasWidth / canvasHeight;
      const pdfRatio = widthMM / heightMM;
      
      // 调整PDF尺寸以匹配图像比例
      let finalWidth = widthMM;
      let finalHeight = heightMM;
      
      if (Math.abs(imgRatio - pdfRatio) > 0.01) {
        finalHeight = finalWidth / imgRatio;
      }
      
      // 创建PDF
      if (options.onLoading) {
        options.onLoading(true, `正在生成${pageCount > 1 ? pageCount + '页' : ''}PDF文件 (4/4)...`);
      }
      await new Promise(resolve => setTimeout(resolve, 100));
      
      try {
        // 添加首页图像
        pdf.addImage(dataURL, 'PNG', 0, 0, finalWidth, finalHeight);
        
        // 如果需要多页
        if (pageCount > 1) {
          // 如果选择重复内容，则添加相同内容的页面
          if (repeatContent) {
            for (let i = 1; i < pageCount; i++) {
              pdf.addPage([widthMM, heightMM], orientation);
              pdf.addImage(dataURL, 'PNG', 0, 0, finalWidth, finalHeight);
              
              if (options.onLoading && i % 5 === 0) {
                options.onLoading(true, `正在添加第 ${i+1}/${pageCount} 页...`);
                await new Promise(resolve => setTimeout(resolve, 10)); // 仅用于更新UI
              }
            }
          } else {
            // 如果选择不重复内容，则添加空白页
            for (let i = 1; i < pageCount; i++) {
              pdf.addPage([widthMM, heightMM], orientation);
              // 页面保持空白，或者可以添加页码等基本元素
              
              // 可选：添加页码
              pdf.setFontSize(8);
              pdf.text(`第 ${i+1} 页`, finalWidth / 2, finalHeight - 5, { align: 'center' });
              
              if (options.onLoading && i % 5 === 0) {
                options.onLoading(true, `正在添加第 ${i+1}/${pageCount} 页...`);
                await new Promise(resolve => setTimeout(resolve, 10)); // 仅用于更新UI
              }
            }
          }
          
          console.log(`已成功添加${pageCount}页内容`);
        }
      } catch (error) {
        console.error('添加图像到PDF时出错，尝试降低质量:', error);
        
        if (options.onLoading) {
          options.onLoading(true, '正在尝试备用方案...');
        }
        
        // 如果失败，降低图像质量
        try {
          pdf.deletePage(1); // 删除可能已添加但有问题的第一页
          pdf.addPage([widthMM, heightMM], orientation); // 重新添加第一页
          
          const fallbackURL = this.fabricInstance.toDataURL({
            format: 'png',
            quality: 0.8,
            multiplier: 2,
            backgroundColor: '#FFFFFF'
          });
          
          pdf.addImage(fallbackURL, 'PNG', 0, 0, finalWidth, finalHeight);
          
          // 如果需要多页
          if (pageCount > 1) {
            if (repeatContent) {
              for (let i = 1; i < pageCount; i++) {
                pdf.addPage([widthMM, heightMM], orientation);
                pdf.addImage(fallbackURL, 'PNG', 0, 0, finalWidth, finalHeight);
              }
            } else {
              for (let i = 1; i < pageCount; i++) {
                pdf.addPage([widthMM, heightMM], orientation);
                // 页面保持空白，或者可以添加页码等基本元素
                pdf.setFontSize(8);
                pdf.text(`第 ${i+1} 页`, finalWidth / 2, finalHeight - 5, { align: 'center' });
              }
            }
          }
        } catch (error2) {
          console.error('降低质量后仍然失败，使用最低质量:', error2);
          
          if (options.onLoading) {
            options.onLoading(true, '正在使用应急方案...');
          }
          
          // 重置PDF
          pdf.deletePage(1);
          pdf.addPage([widthMM, heightMM], orientation);
          
          // 最终的回退方案
          const lastResortURL = this.fabricInstance.toDataURL({
            format: 'png',
            quality: 0.5,
            multiplier: 1,
            backgroundColor: '#FFFFFF'
          });
          
          pdf.addImage(lastResortURL, 'PNG', 0, 0, finalWidth, finalHeight);
          
          // 如果需要多页
          if (pageCount > 1) {
            if (repeatContent) {
              for (let i = 1; i < pageCount; i++) {
                pdf.addPage([widthMM, heightMM], orientation);
                pdf.addImage(lastResortURL, 'PNG', 0, 0, finalWidth, finalHeight);
              }
            } else {
              for (let i = 1; i < pageCount; i++) {
                pdf.addPage([widthMM, heightMM], orientation);
                // 页面保持空白，或者可以添加页码等基本元素
                pdf.setFontSize(8);
                pdf.text(`第 ${i+1} 页`, finalWidth / 2, finalHeight - 5, { align: 'center' });
              }
            }
          }
        }
      }
      
      // 保存PDF
      if (options.onLoading) {
        options.onLoading(true, '正在保存PDF文件...');
      }
      await new Promise(resolve => setTimeout(resolve, 300));
      pdf.save(filename || `${this.templateName || '预览模板'}.pdf`);
      
      // 成功回调
      if (options.onSuccess) {
        options.onSuccess({
          pageCount,
          repeatContent,
          widthMM,
          heightMM,
          orientation
        });
      }
    } catch (error) {
      console.error('导出PDF失败:', error);
      if (options.onError) {
        options.onError(error);
      }
      throw error;
    } finally {
      // 恢复原始背景色
      if (originalBg !== '#FFFFFF') {
        this.fabricInstance.backgroundColor = originalBg;
        this.fabricInstance.renderAll();
      }
      
      // 隐藏加载状态
      if (options.onLoading) {
        options.onLoading(false);
      }
    }
  }

  /**
   * 导出为图片
   * @param {string} filename - 文件名，默认使用模板名
   * @param {Object} options - 导出选项
   * @returns {Promise<string>} 成功时返回图片数据URL，失败时抛出错误
   */
  async exportToImage(filename = null, options = {}) {
    if (!this.isCanvasReady || !this.fabricInstance) {
      throw new Error('画布未准备好');
    }
    
    try {
      if (options.onLoading) {
        options.onLoading(true, '正在导出图片...');
      }
      
      // 保存原始背景色
      const originalBg = this.fabricInstance.backgroundColor;
      
      // 设置背景颜色
      this.fabricInstance.backgroundColor = '#FFFFFF';
      
      // 强制重新渲染画布，确保获取最新内容
      this.fabricInstance.requestRenderAll();
      
      // 使用较高分辨率导出图片
      const multiplier = options.multiplier || 2;
      
      try {
        // 高质量导出
        const dataURL = this.fabricInstance.toDataURL({
          format: 'png',
          quality: 1.0,
          multiplier: multiplier,
          backgroundColor: '#FFFFFF',
          enableRetinaScaling: true  // 启用高分辨率支持
        });
        
        // 恢复原始背景色
        if (originalBg !== '#FFFFFF') {
          this.fabricInstance.backgroundColor = originalBg;
          this.fabricInstance.renderAll();
        }
        
        // 如果要下载而不仅仅是返回数据URL
        if (options.download !== false) {
          const outputFilename = filename || `${this.templateName || '预览模板'}.png`;
          // 创建临时链接并下载
          const link = document.createElement('a');
          link.download = outputFilename;
          link.href = dataURL;
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        }
        
        if (options.onLoading) {
          options.onLoading(false);
        }
        
        if (options.onSuccess) {
          options.onSuccess(dataURL);
        }
        
        return dataURL;
      } catch (error) {
        console.error('导出高质量图片失败，尝试降低质量:', error);
        
        // 如果失败，尝试降低分辨率
        const fallbackURL = this.fabricInstance.toDataURL({
          format: 'png',
          quality: 0.8,
          multiplier: 1,
          backgroundColor: '#FFFFFF'
        });
        
        // 恢复原始背景色
        if (originalBg !== '#FFFFFF') {
          this.fabricInstance.backgroundColor = originalBg;
          this.fabricInstance.renderAll();
        }
        
        if (options.download !== false) {
          const outputFilename = filename || `${this.templateName || '预览模板'}.png`;
          const link = document.createElement('a');
          link.download = outputFilename;
          link.href = fallbackURL;
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        }
        
        if (options.onLoading) {
          options.onLoading(false);
        }
        
        if (options.onSuccess) {
          options.onSuccess(fallbackURL);
        }
        
        return fallbackURL;
      }
    } catch (error) {
      console.error('导出图片失败:', error);
      if (options.onLoading) {
        options.onLoading(false);
      }
      if (options.onError) {
        options.onError(error);
      }
      throw error;
    }
  }
  
  /**
   * 添加文本对象到画布
   * @param {string} text - 文本内容
   * @param {number} left - 左边距（像素）
   * @param {number} top - 上边距（像素）
   * @param {Object} options - 选项
   * @param {boolean} options.autoWidth - 是否根据文本内容自动设置宽度，默认为false
   * @returns {Object} 创建的Fabric.js对象
   */
  addText(text, left, top, options = {}) {
    try {
      if (!this.fabricInstance) {
        console.error('画布未初始化，无法添加文本');
        return null;
      }
      
      // 默认设置
      const fontSize = options.fontSize || 16;
      const fontWeight = options.fontWeight || 'normal';
      const fill = options.fill || '#000000';
      let width = options.width || this.mmToPx(30);
      const customHeight = options.customHeight || this.mmToPx(15);

      // 自动宽度处理
      if (options.autoWidth === true) {
        // 创建临时DOM元素计算文本宽度
        const tempElement = document.createElement('span');
        tempElement.style.visibility = 'hidden';
        tempElement.style.position = 'absolute';
        tempElement.style.fontSize = `${fontSize}px`;
        tempElement.style.fontWeight = fontWeight;
        tempElement.style.whiteSpace = 'nowrap';
        tempElement.textContent = text;
        document.body.appendChild(tempElement);
        
        // 获取文本宽度并增加一些额外空间
        const textWidth = tempElement.offsetWidth;
        width = textWidth * 1.1; // 增加10%的空间，避免文本被截断
        
        // 设置最小宽度
        width = Math.max(width, this.mmToPx(10));

        // 清理临时元素
        document.body.removeChild(tempElement);

        console.log(`自动计算的文本宽度: ${width}px (${this.pxToMm(width).toFixed(2)}mm) 内容: "${text.substring(0, 30)}${text.length > 30 ? '...' : ''}"`);
      }
  
      // 创建文本对象
      const textObj = new Textbox(text, {
        left: Math.round(left),
        top: Math.round(top),
        fontSize,
        fontWeight,
        fill,
        width,
        height: customHeight,
        originX: options.originX || 'center',
        originY: options.originY || 'center',
        editable: false,
        selectable: false,
        borderColor: '#5E9ED6',
        cornerColor: '#5E9ED6',
        cornerSize: 6,
        transparentCorners: false,
        lockRotation: true,
        // 添加多行文本支持
        breakWords: true,       // 允许在单词之间换行
        textAlign: 'left',      // 文本左对齐
        lineHeight: 1.2,        // 行高
        charSpacing: 0,         // 字符间距
        minWidth: 20,           // 最小宽度
        // 启用文本换行功能
        isWrapping: true,       // 启用文本自动换行 
        splitByGrapheme: false, // 按字符拆分而不是按单词拆分
        styles: {},             // 初始化样式对象
        fieldName: options.fieldName || '',
        fieldType: options.fieldType || 'text',
        textTemplate: options.textTemplate || '',
        customData: options.customData || {}  
      });
  
      // 添加自定义类型标识
      textObj.customType = options.customType || 'text';
  
      // 添加到画布
      this.fabricInstance.add(textObj);
  
      return textObj;
    } catch (error) {
      console.error('添加文本时出错:', error);
      return null;
    }
  }
  
  /**
   * 添加表格对象到画布
   * @param {number} left - 左边距（像素）
   * @param {number} top - 上边距（像素）
   * @param {Object} options - 表格选项
   * @returns {Object} 创建的Fabric.js组对象
   */
  addTable(left, top, options = {}) {
    try {
      if (!this.fabricInstance) {
        console.error('画布未初始化，无法添加表格');
        return null;
      }
      
      // 创建表格对象的数组
      const groupObjects = [];
      
      // 获取表格设置
      const headers = options.headers || [];
      const rows = options.tableData || [];
      
      // 计算单元格高度
      const cellHeight = (options.cellHeight || 10) * this.pxPerMmValue;
      const strokeColor = options.strokeColor || '#000000';
      const strokeWidth = options.strokeWidth || 1;
      
      // 计算表格总宽度和每列的像素宽度
      let totalWidth = 0;
      const columnWidths = [];
      
      if (headers.length === 0 && options.cols) {
        // 如果没有定义表头但指定了列数，创建默认表头
        const defaultWidth = (options.width || 100) / options.cols;
        for (let i = 0; i < options.cols; i++) {
          headers.push({
            key: `col${i+1}`,
            label: `列${i+1}`,
            width: defaultWidth
          });
        }
      }
      
      headers.forEach(header => {
        const pixelWidth = (header.width || 35) * this.pxPerMmValue;
        columnWidths.push(pixelWidth);
        totalWidth += pixelWidth;
      });
      
      // 绘制表头
      let currentX = 0;
      headers.forEach((header, index) => {
        // 绘制表头单元格
        const cellRect = new Rect({
          left: currentX,
          top: 0,
          width: columnWidths[index],
          height: cellHeight,
          fill: '#fff',
          stroke: strokeColor,
          strokeWidth: strokeWidth
        });
       
        // 绘制表头文本
        const headerText = new Text(header.label, {
          left: currentX + columnWidths[index] / 2,
          top: cellHeight / 2,
          fontFamily: 'Arial',
          fontSize: options.headerFontSize || 12,
          fontWeight: options.headerBold ? 'bold' : 'normal',
          fill: options.headerTextColor || '#000000',
          originX: 'center',
          originY: 'center',
          selectable: false
        });
        
        // 添加到对象数组
        groupObjects.push(cellRect);
        groupObjects.push(headerText);
        
        currentX += columnWidths[index];
      });
      
      // 如果没有数据行但指定了行数，创建空行
      if (rows.length === 0 && options.rows) {
        for (let i = 0; i < options.rows; i++) {
          const emptyRow = {};
          headers.forEach(header => {
            emptyRow[header.key] = '';
          });
          rows.push(emptyRow);
        }
      }
      
      // 绘制数据行
      rows.forEach((row, rowIndex) => {
        currentX = 0;
        const rowY = (rowIndex + 1) * cellHeight;
        
        headers.forEach((header, index) => {
          // 绘制单元格
          const cellRect = new Rect({
            left: currentX,
            top: rowY,
            width: columnWidths[index],
            height: cellHeight,
            fill: '#ffffff',
            stroke: strokeColor,
            strokeWidth: strokeWidth
          });
          
          // 计算单元格内文本字体大小
          const cellFontSize = Math.min(14, cellHeight * 0.5);
          
          // 获取单元格文本内容
          const cellContent = (row[header.key] !== undefined && row[header.key] !== null) 
            ? String(row[header.key]) 
            : '';
          
          // 绘制单元格文本
          const cellText = new Text(cellContent, {
            left: currentX + columnWidths[index] / 2,
            top: rowY + cellHeight / 2,
            fontFamily: 'Arial',
            fontSize: cellFontSize,
            fill: '#000000',
            originX: 'center',
            originY: 'center',
            textAlign: 'center',
            selectable: false
          });
          
          // 添加到对象数组
          groupObjects.push(cellRect);
          groupObjects.push(cellText);
          
          currentX += columnWidths[index];
        });
      });
      
      // 如果没有对象，返回null
      if (groupObjects.length === 0) {
        console.warn('没有创建任何表格对象');
        return null;
      }
      
      // 创建表格组
      const tableGroup = new Group(groupObjects, {
        left: left,
        top: top,
        selectable: false
      });
      
      // 设置自定义属性
      tableGroup.customType = 'table';
      tableGroup.fieldName = options.fieldName;
      
      // 添加到画布
      this.fabricInstance.add(tableGroup);
      
      return tableGroup;
    } catch (error) {
      console.error('创建表格对象失败:', error, options);
      return null;
    }
  }
  
  /**
   * 添加线条对象到画布
   * @param {number} left - 左边距（像素）
   * @param {number} top - 上边距（像素）
   * @param {Object} options - 线条选项
   * @returns {Object} 创建的Fabric.js线条对象
   */
  addLine(left, top, options = {}) {
    try {
      if (!this.fabricInstance) {
        console.error('画布未初始化，无法添加线条');
        return null;
      }
      
      // 计算线条长度
      let lineArray = [0, 0, 100, 0]; // 默认水平线
      
      if (options.Line && Array.isArray(options.Line)) {
        lineArray = [];
      options.Line.forEach(item => {  
          if (item > 0) {
          item = this.mmToPx(item);
        }
        lineArray.push(item);
      });
      }
  
      const time = new Date().getTime();
      const key = (options.key || 'line') + '_' + time;
  
      const line = new Line(lineArray, {
        left: Math.round(left),
        top: top,
        stroke: options.stroke || '#000000',
        strokeWidth: options.strokeWidth || 1,
        strokeDashArray: options.strokeDashArray || null,
        originX: options.originX || 'left',
        originY: options.originY || 'center',
        selectable: false
      });
      
      // 设置自定义属性
      line.customType = options.customType || 'horizontalLine';
      line.fieldName = key;
      
      // 添加到画布
      this.fabricInstance.add(line);
      
      return line;
    } catch (error) {
      console.error('添加线条时出错:', error);
      return null;
    }
  }
  
  /**
   * 添加条形码对象到画布
   * @param {string} value - 条形码内容
   * @param {number} left - 左边距（像素）
   * @param {number} top - 上边距（像素）
   * @param {Object} options - 条形码选项
   * @returns {Promise<Object>} 创建的Fabric.js图像对象
   */
  async addBarcode(value, left, top, options = {}) {
    try {
      if (!this.fabricInstance) {
        console.error('画布未初始化，无法添加条形码');
        return null;
      }
      
      // 创建临时canvas用于生成条形码
      const tempCanvas = document.createElement('canvas');
      tempCanvas.width = 800;
      tempCanvas.height = 200;
      tempCanvas.style.display = 'none';
      document.body.appendChild(tempCanvas);
  
      // 设置条形码内容
      const content = value || "1234567890";
  
      // 固定条形码整体宽度（毫米）和高度（毫米）
      const barcodeWidthMM = options.width || 60;
      const barcodeHeightMM = options.height || 15;
  
      // 转换为像素
      const barcodeWidthPx = this.mmToPx(barcodeWidthMM);
      const barcodeHeightPx = this.mmToPx(barcodeHeightMM);
  
      // 根据内容长度动态计算条宽度
      const moduleWidth = 2;
      const margin = 10;
  
      // 生成条形码
      try {
      JsBarcode(tempCanvas, content, {
        format: options.format || 'CODE128',
        width: moduleWidth,
        height: barcodeHeightPx - 30,
        displayValue: options.displayValue !== false,
        fontSize: 14,
        textMargin: 5,
        margin: margin,
        background: '#FFFFFF',
        lineColor: '#000000'
      });
      } catch (barcodeError) {
        console.error('生成条形码失败:', barcodeError);
        document.body.removeChild(tempCanvas);
        return null;
      }
  
      // 获取图像数据
      const dataUrl = tempCanvas.toDataURL('image/png');
      document.body.removeChild(tempCanvas);
  
      // 创建一个Promise并返回，以处理异步图像加载
      return new Promise((resolve, reject) => {
        Image.fromURL(dataUrl)
          .then(img => {
            if (!img) {
              console.error('创建条形码图片对象失败');
              reject(new Error('创建条形码图片对象失败'));
              return;
            }
  
            // 计算缩放比例，确保宽度为目标宽度
            const scaleX = barcodeWidthPx / img.width;
            const scaleY = barcodeHeightPx / img.height;
  
            // 边框设置
            const hasBorder = options.border && options.border.show;
            
            // 设置图片属性
            img.set({
              left: Math.round(left),
              top: Math.round(top),
              scaleX: scaleX,
              scaleY: scaleY,
              originX: options.originX || 'left',
              originY: options.originY || 'top',
              selectable: false,
              stroke: hasBorder ? (options.border.color || '#000000') : undefined,
              strokeWidth: hasBorder ? (options.border.width || 0) : 0,
              strokeDashArray: hasBorder && options.border.dashArray ? options.border.dashArray : null
            });
  
            // 设置自定义属性
            img.customType = 'barcode';
            img.barcodeValue = content;
            img.barcodeFormat = options.format || 'CODE128';
            img.displayValue = options.displayValue !== false;
            img.fieldName = options.fieldName || '';
            img.fieldType = 'barcode';
            img.textTemplate = options.textTemplate || '${data}';
            img.border = options.border || { show: false };
  
            // 添加到画布
            this.fabricInstance.add(img);
  
            resolve(img);
          })
          .catch(error => {
            console.error('加载条形码图片失败:', error);
            reject(error);
          });
      });
    } catch (error) {
      console.error('添加条形码时出错:', error);
      return Promise.reject(error);
    }
  }

  /**
   * 填充模板中的占位符
   * @param {Object} template - 模板数据
   * @param {Object} data - 要填充的数据
   * @param {string} printTimeFieldId - 打印时间字段ID，可选
   * @returns {Object} 填充后的模板
   */
  fillTemplateData(template, data, printTimeFieldId = null) {
    if (!template || !data) {
      console.error('填充模板数据失败: 无效的模板或数据');
      return template;
    }
    
    try {
      // 深拷贝模板以避免修改原始模板
      const filledTemplate = JSON.parse(JSON.stringify(template));
      
      // 处理对象
      filledTemplate.objects = filledTemplate.objects.map(obj => {
        // 如果是文本类型且包含占位符
        if (obj.type === 'text' && obj.textTemplate?.includes('${data}')) {
          // 获取字段名称
          const fieldName = obj.fieldName;
          
          // 如果不是自定义文本字段且在数据中有对应值
          if (!fieldName.startsWith('customTitle_') && data[fieldName]) {
            // 检查是否是日期时间字段
            let fieldValue = data[fieldName];
            
            // 以下是一些常见的可能包含日期时间的字段名称
            const dateTimeFields = ['time', 'date', 'Time', 'Date', 'EntryTime', 'CreateTime', 'UpdateTime'];
            const isDateTimeField = dateTimeFields.some(term => fieldName.includes(term));
            
            // 如果是日期时间字段，尝试格式化为标准格式
            if (isDateTimeField && typeof fieldValue === 'string') {
              try {
                // 如果已经是标准格式，则不做处理
                if (!/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(fieldValue)) {
                  // 尝试解析日期
                  const date = new Date(fieldValue);
                  if (!isNaN(date.getTime())) {
                    // 格式化为标准格式
                    fieldValue = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
                  }
                }
              } catch (e) {
                console.error('日期格式化失败:', e);
              }
            }
            
            // 替换占位符
            obj.textTemplate = obj.textTemplate.replace('${data}', fieldValue);
            obj.text = obj.textTemplate;
            
            // 如果有initialData，也需要更新
            if (obj.initialData) {
              try {
                const initialData = JSON.parse(obj.initialData);
                initialData.textTemplate = obj.textTemplate;
                obj.initialData = JSON.stringify(initialData);
              } catch (e) {
                console.error('处理initialData失败:', e);
              }
            }
          }
        }
        // 如果是条形码类型
        else if (obj.type === 'barcode' && data[obj.fieldName]) {
          obj.barcodeValue = data[obj.fieldName];
          
          // 如果有initialData，也需要更新
          if (obj.initialData) {
            try {
              const initialData = JSON.parse(obj.initialData);
              initialData.barcodeValue = data[obj.fieldName];
              obj.initialData = JSON.stringify(initialData);
            } catch (e) {
              console.error('处理条形码initialData失败:', e);
            }
          }
        }
        // 如果是表格类型
        else if (obj.type === 'table' && data[obj.fieldName]) {
          try {
            // 解析表格的initialData
            const tableInitialData = JSON.parse(obj.initialData);
            
            // 用新的表格数据替换原来的表格数据
            if (Array.isArray(data[obj.fieldName])) {
              tableInitialData.tableData = data[obj.fieldName];
              obj.initialData = JSON.stringify(tableInitialData);
            }
          } catch (e) {
            console.error('处理表格数据失败:', e);
          }
        }
        
        return obj;
      });
      
      // 添加打印时间
      const timeFieldId = printTimeFieldId || this.printTimeFieldId;
      const printTimeObj = filledTemplate.objects.find(obj => obj.fieldName === timeFieldId);
      
      if (printTimeObj) {
        const now = new Date();
        // 格式化时间为"YYYY-MM-DD HH:MM:SS"格式
        const formattedDate = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;
        
        // 使用标准格式的时间
        printTimeObj.textTemplate = `打印时间: ${formattedDate}`;
        printTimeObj.text = printTimeObj.textTemplate;
        
        if (printTimeObj.initialData) {
          try {
            const initialData = JSON.parse(printTimeObj.initialData);
            initialData.textTemplate = printTimeObj.textTemplate;
            printTimeObj.initialData = JSON.stringify(initialData);
          } catch (e) {
            console.error('处理打印时间失败:', e);
          }
        }
      }
      
      return filledTemplate;
    } catch (error) {
      console.error('填充模板数据失败:', error);
      return template; // 返回原始模板
    }
  }
  
  /**
   * 处理模板和数据并渲染到画布
   * @param {Object|string} templateData - 模板JSON数据对象或字符串
   * @param {Object} data - 要填充的数据
   * @param {HTMLCanvasElement|Object} canvasElement - Canvas元素或Vue ref
   * @param {Object} options - 选项
   * @returns {Promise<boolean>} 渲染是否成功
   */
  async renderTemplateWithData(templateData, data, canvasElement, options = {}) {
    try {
      console.log('开始处理模板和数据并渲染...');
      
      // 重置状态，确保每次调用都是全新的渲染
      this.isCanvasReady = false;
      if (this.fabricInstance) {
        this.fabricInstance.dispose();
        this.fabricInstance = null;
      }
      
      // 解析模板（如果是字符串）
      const parsedTemplate = typeof templateData === 'string' ? JSON.parse(templateData) : templateData;
      
      // 填充数据
      console.log('填充模板数据...');
      const filledTemplate = this.fillTemplateData(parsedTemplate, data);
      
      // 获取画布尺寸
      const { width, height, pxPerMm } = filledTemplate.canvas;
      
      // 初始化画布
      console.log('初始化画布...');
      const initResult = await this.initCanvas(canvasElement, width, height, pxPerMm, false);
      
      if (!initResult) {
        console.error('画布初始化失败');
        return false;
      }
      
      // 渲染模板
      console.log('渲染模板...');
      const renderResult = await this.renderFromJSON(filledTemplate);
      
      if (!renderResult) {
        console.error('模板渲染失败');
        return false;
      }
      
      // 强制重新渲染最终结果
      this.fabricInstance.requestRenderAll();
      
      console.log('模板渲染成功');
      return true;
    } catch (error) {
      console.error('处理模板和数据并渲染失败:', error);
      return false;
    }
  }
  
  /**
   * 渲染模板并打印为PDF (集成入口方法)
   * @param {Object|string} templateData - 模板JSON数据对象或字符串
   * @param {Object} data - 要填充的数据
   * @param {HTMLCanvasElement|Object} canvasElement - Canvas元素或Vue ref
   * @param {string} filename - PDF文件名
   * @param {Object} options - 选项
   * @param {Function} options.onSuccess - 成功回调
   * @param {Function} options.onError - 错误回调
   * @param {Function} options.onLoading - 加载状态回调
   * @returns {Promise<boolean>} 打印是否成功
   */
  async printTemplateWithData(templateData, data, canvasElement, filename = null, options = {}) {
    try {
      const { onSuccess = () => {}, onError = () => {}, onLoading = () => {} } = options;
      
      // 加载提示
      onLoading(true, '正在准备渲染...');
      
      // 渲染模板
      const renderSuccess = await this.renderTemplateWithData(templateData, data, canvasElement);
      
      if (!renderSuccess) {
        const error = new Error('渲染模板失败');
        onError(error);
        onLoading(false);
        return false;
      }
      
      // 导出PDF
      onLoading(true, '正在导出PDF...');
      
      // 确定文件名
      const outputFilename = filename || `${this.templateName || '打印模板'}.pdf`;
      
      // 导出PDF
      await this.exportToPDF(outputFilename, {
        onSuccess,
        onError,
        onLoading
      });
      
      return true;
    } catch (error) {
      console.error('渲染模板并打印失败:', error);
      if (options.onError) {
        options.onError(error);
      }
      if (options.onLoading) {
        options.onLoading(false);
      }
      return false;
    }
  }
  
  /**
   * 创建PDF Blob对象
   * @param {Object|string} templateData - 模板JSON数据对象或字符串
   * @param {Object} data - 要填充的数据
   * @param {HTMLCanvasElement|Object} canvasElement - Canvas元素或Vue ref
   * @param {Object} options - 选项
   * @param {Function} options.onSuccess - 成功回调
   * @param {Function} options.onError - 错误回调
   * @param {Function} options.onLoading - 加载状态回调
   * @param {number} [options.pages=1] - PDF页数，默认为1页
   * @param {boolean} [options.repeatContent=false] - 是否重复第一页内容，默认为true
   * @returns {Promise<Blob>} PDF的Blob对象
   */
  async createPdfBlob(templateData, data, canvasElement, options = {}) {
    try {
      const { onSuccess = () => {}, onError = () => {}, onLoading = () => {} } = options;
      
      // 获取自定义页数设置
      const pageCount = options.pages && options.pages > 0 ? parseInt(options.pages) : 1;
      const repeatContent = options.repeatContent||false; // 默认为false
      
      // 加载提示
      if (onLoading) onLoading(true, '正在准备生成PDF...');
      
      // 渲染模板
      const renderSuccess = await this.renderTemplateWithData(templateData, data, canvasElement);
      
      if (!renderSuccess) {
        const error = new Error('渲染模板失败');
        if (onError) onError(error);
        if (onLoading) onLoading(false);
        throw error;
      }
      
      // 确保fabric实例存在
      if (!this.fabricInstance) {
        const error = new Error('Fabric实例不存在');
        if (onError) onError(error);
        if (onLoading) onLoading(false);
        throw error;
      }
      
      if (onLoading) onLoading(true, `正在生成${pageCount > 1 ? pageCount + '页' : ''}PDF...`);
      
      // 获取画布数据
      const canvasWidth = this.fabricInstance.getWidth();
      const canvasHeight = this.fabricInstance.getHeight();
      
      // 计算毫米尺寸
      const pxPerMm = this.pxPerMmValue;
      const widthMM = canvasWidth / pxPerMm;
      const heightMM = canvasHeight / pxPerMm;
      
      // 确定PDF方向
      const orientation = widthMM > heightMM ? 'landscape' : 'portrait';
      
      console.log(`画布尺寸: ${canvasWidth}x${canvasHeight}px, 毫米尺寸: ${widthMM}x${heightMM}mm`);
      console.log(`PDF页数: ${pageCount}, 是否重复内容: ${repeatContent}`);
      
      // 创建PDF文档
      const jsPdfInstance = new jsPDF({
        orientation: orientation,
        unit: 'mm',
        format: [widthMM, heightMM],
        compress: true
      });
      
      try {
        // 创建高质量图像数据
        if (onLoading) onLoading(true, '正在生成高清图像...');
        
        // 动态调整multiplier以获得更清晰的图像
        let multiplier = 3;
        if (canvasWidth * canvasHeight > 1000000) {
          multiplier = 3;
        }
        if (canvasWidth * canvasHeight > 2000000) {
          multiplier = 2;
        }
        
        console.log(`使用图像质量倍数: ${multiplier}x, 画布尺寸: ${canvasWidth}x${canvasHeight}px`);
        
        const dataURL = this.fabricInstance.toDataURL({
          format: 'png',
          quality: 1.0,
          multiplier: multiplier,
          backgroundColor: '#FFFFFF'
        });
        
        // 比例计算
        const imgRatio = canvasWidth / canvasHeight;
        const pdfRatio = widthMM / heightMM;
        
        // 调整PDF尺寸以匹配图像比例
        let finalWidth = widthMM;
        let finalHeight = heightMM;
        
        if (Math.abs(imgRatio - pdfRatio) > 0.01) {
          finalHeight = finalWidth / imgRatio;
        }
        
        // 添加首页图像
        jsPdfInstance.addImage(dataURL, 'PNG', 0, 0, finalWidth, finalHeight);
        
        // 如果需要多页
        if (pageCount > 1) {
          if (onLoading) onLoading(true, `正在添加多页内容...`);
          
          // 如果选择重复内容，则添加相同内容的页面
          if (repeatContent) {
            for (let i = 1; i < pageCount; i++) {
              jsPdfInstance.addPage([widthMM, heightMM], orientation);
              jsPdfInstance.addImage(dataURL, 'PNG', 0, 0, finalWidth, finalHeight);
              
              if (onLoading && i % 5 === 0) {
                onLoading(true, `正在处理第 ${i+1}/${pageCount} 页...`);
                await new Promise(resolve => setTimeout(resolve, 10)); // 仅用于更新UI
              }
            }
          } else {
            // 如果选择不重复内容，则添加空白页
            for (let i = 1; i < pageCount; i++) {
              jsPdfInstance.addPage([widthMM, heightMM], orientation);
              
              // 可选：添加页码
              jsPdfInstance.setFontSize(8);
              jsPdfInstance.text(`第 ${i+1} 页`, finalWidth / 2, finalHeight - 5, { align: 'center' });
              
              if (onLoading && i % 5 === 0) {
                onLoading(true, `正在处理第 ${i+1}/${pageCount} 页...`);
                await new Promise(resolve => setTimeout(resolve, 10)); // 仅用于更新UI
              }
            }
          }
          
          console.log(`已成功添加${pageCount}页内容`);
        }
      } catch (error) {
        console.error('生成高质量PDF失败，尝试降低质量:', error);
        
        if (onLoading) onLoading(true, '正在尝试备用方案...');
        
        try {
          // 重置PDF
          jsPdfInstance.deletePage(1);
          jsPdfInstance.addPage([widthMM, heightMM], orientation);
          
          // 使用较低质量
          const fallbackURL = this.fabricInstance.toDataURL({
            format: 'png',
            quality: 0.8,
            multiplier: 2,
            backgroundColor: '#FFFFFF'
          });
          
          jsPdfInstance.addImage(fallbackURL, 'PNG', 0, 0, finalWidth, finalHeight);
          
          // 如果需要多页
          if (pageCount > 1) {
            if (repeatContent) {
              for (let i = 1; i < pageCount; i++) {
                jsPdfInstance.addPage([widthMM, heightMM], orientation);
                jsPdfInstance.addImage(fallbackURL, 'PNG', 0, 0, finalWidth, finalHeight);
                
                if (onLoading && i % 5 === 0) {
                  onLoading(true, `正在处理第 ${i+1}/${pageCount} 页(备用方案)...`);
                  await new Promise(resolve => setTimeout(resolve, 10));
                }
              }
            } else {
              // 如果选择不重复内容，则添加空白页
              for (let i = 1; i < pageCount; i++) {
                jsPdfInstance.addPage([widthMM, heightMM], orientation);
                
                // 可选：添加页码
                jsPdfInstance.setFontSize(8);
                jsPdfInstance.text(`第 ${i+1} 页`, finalWidth / 2, finalHeight - 5, { align: 'center' });
                
                if (onLoading && i % 5 === 0) {
                  onLoading(true, `正在处理第 ${i+1}/${pageCount} 页(备用方案)...`);
                  await new Promise(resolve => setTimeout(resolve, 10));
                }
              }
            }
          }
        } catch (error2) {
          console.error('降低质量后仍然失败，使用最低质量:', error2);
          
          // 重置PDF
          jsPdfInstance.deletePage(1);
          jsPdfInstance.addPage([widthMM, heightMM], orientation);
          
          // 最终的回退方案，使用最低质量
          const lastResortURL = this.fabricInstance.toDataURL({
            format: 'png',
            quality: 0.5,
            multiplier: 1,
            backgroundColor: '#FFFFFF'
          });
          
          jsPdfInstance.addImage(lastResortURL, 'PNG', 0, 0, finalWidth, finalHeight);
          
          // 如果需要多页
          if (pageCount > 1) {
            if (repeatContent) {
              for (let i = 1; i < pageCount; i++) {
                jsPdfInstance.addPage([widthMM, heightMM], orientation);
                jsPdfInstance.addImage(lastResortURL, 'PNG', 0, 0, finalWidth, finalHeight);
                
                if (onLoading && i % 5 === 0) {
                  onLoading(true, `正在处理第 ${i+1}/${pageCount} 页(应急方案)...`);
                  await new Promise(resolve => setTimeout(resolve, 10));
                }
              }
            } else {
              // 如果选择不重复内容，则添加空白页
              for (let i = 1; i < pageCount; i++) {
                jsPdfInstance.addPage([widthMM, heightMM], orientation);
                
                // 可选：添加页码
                jsPdfInstance.setFontSize(8);
                jsPdfInstance.text(`第 ${i+1} 页`, finalWidth / 2, finalHeight - 5, { align: 'center' });
                
                if (onLoading && i % 5 === 0) {
                  onLoading(true, `正在处理第 ${i+1}/${pageCount} 页(应急方案)...`);
                  await new Promise(resolve => setTimeout(resolve, 10));
                }
              }
            }
          }
        }
      }
      
      // 生成Blob对象
      const pdfBlob = jsPdfInstance.output('blob');
      
      if (onSuccess) onSuccess({
        blob: pdfBlob,
        pageCount,
        repeatContent,
        widthMM,
        heightMM,
        orientation
      });
      
      if (onLoading) onLoading(false);
      
      return pdfBlob;
    } catch (error) {
      console.error('创建PDF Blob失败:', error);
      if (options.onError) {
        options.onError(error);
      }
      if (options.onLoading) {
        options.onLoading(false);
      }
      throw error;
    }
  }
}

export default CanvasRenderer; 